home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / zousan / src / zousan.c < prev    next >
Text File  |  1994-06-01  |  13KB  |  570 lines

  1. /*
  2.  *   tiff16/256色 -> tiff32k色  変換プログラム 'ぞうさん'
  3.  *                  (C)1993,1994  By N.Takahashi
  4.  *
  5.  *      ver0.61 1994/02/06   パレット無しのTiffデータに対応
  6.  *      ver0.6  1994/02/05   新Tiff関数へ変更(圧縮形式に対応)
  7.  *      ver0.5  1994/01/13   再度、変換ル-チンの高速化
  8.  *      ver0.4  1994/01/05   ワイルドカード対応、バグ修正etc.
  9.  *      ver0.3  1994/01/04   変換ル-チンの高速化
  10.  *      ver0.2  1994/01/04   ファイル分割(zousan.c tiff.c graph.c)
  11.  *      ver0.1  1993/11/11   初版
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <conio.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include <dos.h>
  20. #include <fcntl.h>
  21. #include <EGB.h>
  22.  
  23. #include "tiff2.h"        /* 拡張ライブラリIを買わないといけないかな(^^;) */
  24. #include "graph.h"
  25.  
  26.  
  27. /* Compile 方法 */
  28. /*   hcc zousan tiff2 graph -stack 200000   */
  29.  
  30.  
  31. /* Prototype function */
  32. void sum_ydata( int *ydt, int *sum, int *cnt );
  33. void ren_file( void );
  34. int exp_wild( char *path, char *file, char *dpath, char *dfile );
  35. int isoldfile( char *fname );
  36. void split_path( char *path, char *file, char *wd );
  37. void sum_gdata256( int x, int y, int *cg, int *cr, int *cb );
  38. void sum_gdata16( int x, int y, int *cg, int *cr, int *cb );
  39. void title( void );
  40. void usage( void );
  41. int zousan( void );
  42. void make_color( int *b, int *r, int *g, int b1, int r1, int g1, int hi );
  43. int convert32k( void );
  44. void adj_palette( char *pal, int col );
  45.  
  46.  
  47. /* マクロ定義 */
  48. #define    CVCR(b,r,g)    ((-(b)*816+(r)*5020-(g)*4203)/10000)
  49. #define CVCB(b,r,g)    (((b)*5020-(r)*1812-(g)*3214)/10000)
  50. #define CVY(b,r,g)    (((b)*1446+(r)*2955+(g)*5899)/10000)
  51. #define CVY2(b,r,g)    (((b)*1446+(r)*2955+(g)*5899))
  52.  
  53. #define CVB(cr,cb,y) ((y)*9719+(cr)*487+(cb)*17201)
  54. #define CVR(cr,cb,y) ((y)*9707+(cr)*14021-(cb)*516)
  55. #define CVG(cr,cb,y) ((y)*9707-(cr)*7142-(cb)*3957)
  56.  
  57. #define    ATTR        (_A_NORMAL|_A_RDONLY|_A_HIDDEN)
  58.  
  59.  
  60. /* Global variable */
  61.  
  62. PALETTE16 *Pal16;
  63. PALETTE256 *Pal256;
  64.  
  65. char *Gdata,*Gpal;    /* 画像データ&パレット */
  66. int SizX;            /* 横サイズ */
  67. int SizY;            /* 縦サイズ */
  68. int Gcol=0;            /* 色数     */
  69. char *Ddata;        /* 変換した画像データ */
  70.  
  71. int Blur=0;            /*  Blur = 0 - 100 (Blur)          */
  72. int Tone=0;            /*  Tone = 0 - 100 (Tone of color) */
  73.  
  74. int BlurF=0,ToneF=0,DispF=0;        /* オプション・フラグ */
  75. int CompF=0;
  76.  
  77. int DirX[4]={0,1,0,-1};
  78. int DirY[4]={-1,0,1,0};
  79.  
  80. void (*Sum_gdata)( int x, int y, int *cg, int *cr, int *cb );
  81.  
  82. char *Srcfile=NULL;
  83. char *Dstfile=NULL;
  84.  
  85. #define PATH_MAX    128
  86. #define FILE_MAX    16
  87. char SPath[PATH_MAX];        /* ワイルドカード展開に使用 */
  88. char SFile[FILE_MAX];
  89. char DPath[PATH_MAX];
  90. char DFile[FILE_MAX];
  91.  
  92. int WildF=0,DDirF=0;        /* ワイルドカ-ドを使用できるようにしたら、
  93.                                 結構、制御が複雑になってしまった。 */
  94.  
  95. char Nowfile[128];            /* 現在、処理中のファイル名 */
  96.  
  97.  
  98. /* 使用法 */
  99. void usage( void ) {
  100.     printf( "usage: run386 zousan.exp [option] srcTiff16/256 [dstTiff]\n" );
  101.     printf( "        -b<val>  (Blur)          ,val = 0 - 100\n" );
  102.     printf( "        -t<val>  (Tone of color) ,val = 0 - 100\n" );
  103.     printf( "        -d       (Display only)\n" );
  104.     printf( "        -c       (Compress Tiff file)\n\n" );
  105.     printf( "       default:  16color = -b0 , -t20\n" );
  106.     printf( "                256color = -b0 , -t2\n" );
  107.     exit( 255 );
  108. }
  109.  
  110.  
  111. /* タイトル */
  112. void title( void ) {
  113.     printf( "Tiff16/256色 -> Tiff32k色  変換プログラム 'ぞうさん'\n" );
  114.     printf( "                        (C)1993,1994  By N.Takahashi\n\n" );
  115. }
  116.  
  117.  
  118. /* メイン */
  119. void main( int argc, char *argv[] ) {
  120. int i;
  121.  
  122.     title();
  123.     
  124.     if( argc==1 )
  125.         usage();
  126.     for( i=1; i<argc; i++ ) {                    /* オプション展開 */
  127.         if( argv[i][0]=='-' || argv[i][0]=='/' )
  128.             switch( argv[i][1] ) {                /* 手抜きしてる(^^;) */
  129.                 case 'b':
  130.                 case 'B':
  131.                     Blur=atoi( argv[i]+2 );
  132.                     BlurF=1;
  133.                     break;
  134.                 case 't':
  135.                 case 'T':
  136.                     Tone=atoi( argv[i]+2 );
  137.                     ToneF=1;
  138.                     break;
  139.                 case 'd':
  140.                 case 'D':
  141.                     DispF=1;
  142.                     break;
  143.                 case 'c':
  144.                 case 'C':
  145.                     CompF=1;
  146.                     break;
  147.                 default:
  148.                     usage();
  149.                     break;
  150.             }
  151.         else {
  152.             if( Srcfile==NULL )
  153.                 Srcfile=argv[i];
  154.             else
  155.                 Dstfile=argv[i];
  156.         }
  157.     }
  158.     if( Srcfile==NULL )
  159.         usage();
  160.  
  161.     isoldfile( NULL );        /* 基準時刻のセット */
  162.                             /* 二度、変換しないようにするための準備 */
  163.     
  164.     strcpy( SPath, Srcfile );
  165.     split_path( SPath, SFile, "*.TIF" );
  166.     if( strchr( SFile, '*' )!=NULL || strchr( SFile, '?' )!=NULL ) {
  167.         WildF=1;
  168.     }
  169.     
  170.     if( Dstfile==NULL ) {        /* 何も指定されていないとき */
  171.         strcpy( DPath, SPath );
  172.         *DFile='\0';
  173.     }
  174.     else {                        /* ファイルが指定されているとき */
  175.         strcpy( DPath, Dstfile );
  176.         split_path( DPath, DFile, "" );
  177.         if( WildF ) {
  178.             strcat( DPath, DFile );
  179.             strcat( DPath, "\\" );
  180.             *DFile='\0';
  181.         }
  182.         if( *DFile=='\0' )            /* ディレクトリのみのとき */
  183.             DDirF=1;
  184.     }
  185.     
  186.     exp_wild( SPath, SFile, DPath, DFile );
  187. }
  188.  
  189.  
  190. /* ワイルドカ-ド展開 */
  191. int exp_wild( char *path, char *file, char *dpath, char *dfile ) {
  192. struct find_t fb;
  193. int spl,dpl;
  194. char *c;
  195.     
  196.     spl=strlen( path );
  197.     dpl=strlen( dpath );
  198.     strcat( path, file );
  199.     if( _dos_findfirst( path, ATTR, &fb )==0 ) {
  200.         do {
  201.             path[spl]='\0';
  202.             dpath[dpl]='\0';
  203.             strcat( path, fb.name );
  204.             
  205.             if( isoldfile( path ) ) {
  206.                         /* 二度、変換しないようにするため */
  207.             
  208.                 sprintf( Nowfile, "%-12s : ", fb.name );
  209.                 Srcfile=path;
  210.                 Dstfile=dpath;
  211.                 if( *dfile=='\0' ) {    /* ファイルが指定されていないとき */
  212.                     if( DDirF ) {        /* ディレクトリのみのとき */
  213.                         strcat( dpath, fb.name );
  214.                         zousan();
  215.                     }
  216.                     else {                /* 何も指定されていないとき */
  217.                         strcat( dpath, fb.name );
  218.                         if( ( c=strrchr( dpath, '.' ) )!=NULL ) {
  219.                             *c='\0';
  220.                         }
  221.                         strcat( dpath, ".$$$" );
  222.                         if( zousan()==0 )
  223.                             ren_file();
  224.                     }
  225.                 }
  226.                 else {                    /* ファイルが指定されているとき */
  227.                     strcat( dpath, dfile );
  228.                     zousan();
  229.                 }
  230.             }
  231.         } while( _dos_findnext( &fb )==0 );
  232.         return( 0 );
  233.     }
  234.     else {
  235.         printf( "%-12s : ファイルが見つかりません。\n", _strupr(file) );
  236.     }
  237.     return( 1 );
  238. }
  239.  
  240.  
  241. /* タイムスタンプとシステムタイムとの比較 */
  242. /* 使用前に基準時刻をセットしておくこと => isoldfile( NULL ) */
  243. int isoldfile( char *fname ) {
  244. static unsigned int sdate=0, stime=0;
  245. struct dosdate_t sdt;
  246. struct dostime_t stm;
  247. unsigned int fdt,ftm;
  248. int hd;
  249.     
  250.     if( fname==NULL ) {
  251.         _dos_getdate( &sdt );
  252.         sdate=((sdt.year-1980)<<9)+(sdt.month<<5)+sdt.day;
  253.         _dos_gettime( &stm );
  254.         stime=(stm.hour<<11)+(stm.minute<<5)+(stm.second>>1);
  255.     }
  256.     else {
  257.         if( _dos_open( fname, _O_RDONLY, &hd )!=0 )
  258.             return( -1 ); 
  259.         _dos_getftime( hd, &fdt, &ftm );
  260.         _dos_close( hd );
  261.         if( fdt<sdate || (fdt==sdate && ftm<stime) )
  262.             return( 1 );
  263.     }
  264.     return( 0 );
  265. }
  266.  
  267.  
  268. /* ファイル名の交換 */
  269. void ren_file( void ) {
  270. char path[128],*c;
  271.                                     /* dst.$$$ を dst.TIF へ */
  272.                                     /* src.TIF を src.$IF へ */
  273.     strcpy( path, Srcfile );
  274.     if( ( c=strrchr( path, '.' ) )!=NULL ) {
  275.         *c='\0';
  276.     }
  277.     strcat( path, ".$IF" );
  278.     rename( Srcfile, path );
  279.  
  280.     strcpy( path, Dstfile );
  281.     if( ( c=strrchr( path, '.' ) )!=NULL ) {
  282.         *c='\0';
  283.     }
  284.     strcat( path, ".TIF" );
  285.     rename( Dstfile, path );
  286. }
  287.  
  288.  
  289. /* PATH名とファイル名取り出し */
  290. void split_path( char *path, char *file, char *wd ) {
  291. char *c,*c2;
  292.  
  293.     if( ( c=strrchr( path, ':' ) )==NULL ) {
  294.         c=path;
  295.     }
  296.     if( ( c2=strrchr( c, '\\' ) )==NULL ) {
  297.         c2=c;
  298.     }
  299.     if( *c2==':' || *c2=='\\' ) {
  300.         if( *(c2+1)!='\0' ) {
  301.             strcpy( file, c2+1 ); 
  302.             *(c2+1)='\0';
  303.         }
  304.         else
  305.             strcpy( file, wd ); 
  306.     }
  307.     else {
  308.         strcpy( file , path );
  309.         strcpy( path , "" );
  310.     }
  311.                                     /* '.' , '..' 対策 */
  312.     if( strcmp( file, "." )==0 || strcmp( file, ".." )==0 ) {
  313.         strcat( path, file );
  314.         strcat( path, "\\" );
  315.         strcpy( file, wd ); 
  316.     }
  317. }
  318.  
  319.  
  320. /* ぞうさんメイン */
  321. int zousan( void ) {
  322. Tiff *tp;
  323. int rt;
  324.  
  325.     tp=Tiff_new();
  326.                                                 /* Tiff形式ロード */
  327.     rt=Tiff_load( Srcfile, tp );
  328.     if( rt!=Tiff__OK ) {
  329.         printf( "%s%s\n", Nowfile, Tiff_err[rt] );
  330.         return( 1 );
  331.     }
  332.     Tiff_decompress( tp );            /* 圧縮されている場合、展開する */
  333.     Tiff_make_palette( tp );        /* パレットがない場合に作成する */
  334.     
  335.     Tiff_getgraph( &SizX, &SizY, &Gcol, &Gdata, &Gpal, tp );
  336.                                             /* 色数による設定 */
  337.     switch( Gcol ) {
  338.         case 256:
  339.             if( BlurF==0 )            /* デフォルト値 */
  340.                 Blur=0;
  341.             if( ToneF==0 )
  342.                 Tone=2;
  343.             Pal256=(PALETTE256 *)Gpal;
  344.             Sum_gdata=sum_gdata256;
  345.             break;
  346.         case 16:
  347.             if( BlurF==0 )
  348.                 Blur=0;
  349.             if( ToneF==0 )
  350.                 Tone=20;
  351.             Pal16=(PALETTE16 *)Gpal;
  352.             Sum_gdata=sum_gdata16;
  353.             break;
  354.         default:
  355.             printf( "%s扱えないデータ形式です。\n", Nowfile );
  356.             return( 1 );
  357.     }
  358.  
  359.     if( Blur<0 )
  360.         Blur=0;
  361.     if( Blur>100 )
  362.         Blur=100;
  363.     if( Tone<0 )
  364.         Tone=0;
  365.     if( Tone>100 )
  366.         Tone=100;
  367.     
  368.     adj_palette( Gpal, Gcol );        /* パレットデータの調整 */
  369.                                     /* Tiff_load直後のパレットデータは、
  370.                                        そのままでは使いにくい           */
  371.  
  372.     if( (Ddata=(char *)malloc( SizX*SizY/2 ))==NULL ) {
  373.         printf( "メモリが足りません。\n" );
  374.         Tiff_delete( tp );
  375.         return( 1 );
  376.     }
  377.                                         /* 32K色変換 */
  378.     if( convert32k() ) {
  379.         printf( "強制中断します。%*c\n", 60, 0x20 );
  380.         G_dosterm();
  381.         exit( 1 );
  382.     }
  383.                                         /* ディスプレイ表示 */
  384.     if( DispF ) {
  385.         G_screen( 10, 0 );                /* 320*240 3万色 */
  386.         G_screen( 10, 1 );
  387.         G_enlarge( 2, 2, 0, 0, 320, 240 );
  388.         G_active( 1, 3, 1 );
  389.         G_put( 0,0, SizX/2-1,SizY/2-1, Ddata );
  390.         _getch();                        /* 何かキー入力が有るまで待つ */
  391.         G_dosterm();                    /* DOS画面に戻す */
  392.         Tiff_delete( tp );
  393.         free( Ddata );
  394.         return( 1 );
  395.     }
  396.                                         /* Tiff形式セーブ */
  397.     if( Dstfile!=NULL && !DispF ) {
  398.         Tiff_delete( tp );
  399.         tp=Tiff_new();
  400.         Tiff_setgraph( tp, SizX/2, SizY/2, 32768, Ddata, NULL );
  401.         if( CompF )
  402.             Tiff_compress( tp );        /* -c 指定時にデータを圧縮する */
  403.         rt=Tiff_save( Dstfile, tp );
  404.         if( rt!=0 ) {
  405.             printf( "%s%s\n", Nowfile, Tiff_err[rt] );
  406.             Tiff_delete( tp );
  407.             return( 1 );
  408.         }
  409.     }
  410.     Tiff_delete( tp );
  411.     return( 0 );
  412. }
  413.  
  414.  
  415. /* 3万色変換 */
  416. int convert32k( void ) {
  417. int x,y,a,b,hi,bc,bcc;
  418. int cc,cg,cr,cb;
  419. int yc,yg,yr,yb;
  420. int g0,r0,b0;
  421. int xx,yy,xd,yd;
  422. int ydt[16];
  423.  
  424.     for( y=0; y<SizY-1; y+=2 ) {
  425.         if( (y&31)==0 ) {
  426.             printf( "%s変換中です。(%d%)\r", Nowfile, y*100/SizY );
  427.         }
  428.         if( _kbhit() ) {
  429.             if( _getch()==0x1b )
  430.                 return( 1 );
  431.         }
  432.         yd=(y/2*SizX)/2;
  433.         for( x=0; x<SizX-1; x+=2 ) {
  434.             xd=x/2;
  435.             cg=cr=cb=cc=yg=yr=yb=yc=0;        /* 色と輝度の積算 4×4 */
  436.             for( a=-1; a<=2; a++ ) {
  437.                 xx=x+a;
  438.                 for( b=-1; b<=2; b++ ) {
  439.                     yy=y+b;
  440.                     if( xx>=0 && xx<SizX && yy>=0 && yy<SizY ) {
  441.                         Sum_gdata( xx, yy, &g0, &r0, &b0 );
  442.                         ydt[a+1+(b+1)*4]=CVY2( b0, r0, g0 );
  443.                         cg+=g0;
  444.                         cr+=r0;
  445.                         cb+=b0;
  446.                         cc++;
  447.                         if( a>=0 && a<=1 && b>=0 && b<=1 ) {
  448.                             yg+=g0;
  449.                             yr+=r0;
  450.                             yb+=b0;
  451.                             yc++;
  452.                         }
  453.                     }
  454.                     else
  455.                         ydt[a+1+(b+1)*4]=-1;
  456.                 }
  457.             }
  458.             sum_ydata( ydt, &bc, &bcc );
  459.             
  460.             hi=( bcc>0 )?(bc/bcc)/10000 : 0;
  461.             cr/=cc;
  462.             cg/=cc;
  463.             cb/=cc;
  464.             yr/=yc;
  465.             yg/=yc;
  466.             yb/=yc;
  467.  
  468.             make_color( &cb, &cr, &cg, yb, yr, yg, hi );
  469.  
  470.             /* 色データ書き込み */
  471.             *((unsigned short *)Ddata+xd+yd)=G_color32k(cg, cr, cb);
  472.         }
  473.     }
  474.     printf( "%s変換終了しました。(100%)\n", Nowfile );
  475.     
  476.     return( 0 );
  477. }
  478.  
  479.  
  480. /* 色作成 */
  481. void make_color( int *bb, int *rr, int *gg, int bb1, int rr1, int gg1, int hi ) {
  482. int y,cr,cb,y0,b;
  483.  
  484.         cr=CVCR( *bb, *rr, *gg );                /* YC分離 */
  485.         cb=CVCB( *bb, *rr, *gg );
  486.         y=CVY( bb1, rr1, gg1 );
  487.         y0=CVY( *bb, *rr, *gg );
  488.  
  489.         b=abs(*rr-rr1)+abs(*bb-bb1)+abs(*gg-gg1);
  490.         b=1000/(b+1);
  491.         b+=Blur;
  492.         if( b>100 )
  493.             b=100;
  494.         y+=(y0-y)*b/100;        /* にじみ具合の調整 */
  495.         
  496.         y+=hi*Tone/100;            /* 色調の調整 */
  497.  
  498.         *bb=CVB( cr, cb, y );                    /* RGB色合成 */
  499.         *bb=( *bb>=0 )?(*bb+5000)/10000 : 0;
  500.         *rr=CVR( cr, cb, y );
  501.         *rr=( *rr>=0 )?(*rr+5000)/10000 : 0;
  502.         *gg=CVG( cr, cb, y );
  503.         *gg=( *gg>=0 )?(*gg+5000)/10000 : 0;
  504.  
  505.         if( *bb>255 )
  506.             *bb=255;
  507.         if( *rr>255 )
  508.             *rr=255;
  509.         if( *gg>255 )
  510.             *gg=255;
  511.  
  512. }
  513.  
  514.  
  515. /* パレット調整 */
  516. void adj_palette( char *pal, int col ) {
  517. int i;
  518.                                 /* Tiffのパレットデータの調整 */
  519.     for( i=0; i<col*3; i++ ) {
  520.         *((unsigned short *)pal+i)=*((unsigned short *)pal+i)>>8;
  521.     }
  522. }
  523.  
  524.  
  525. /* 16色データ取得 */
  526. void sum_gdata16( int x, int y, int *cg, int *cr, int *cb ) {
  527. int cc;
  528.     cc=Gdata[(x+y*SizX)/2];
  529.     if( x&1 )
  530.         cc=cc>>4;
  531.     else
  532.         cc=cc&15;
  533.     *cb=Pal16->blue[cc];    /* パレットによる色変換 */
  534.     *cr=Pal16->red[cc];
  535.     *cg=Pal16->green[cc];
  536. }
  537.  
  538.  
  539. /* 256色データ取得 */
  540. void sum_gdata256( int x, int y, int *cg, int *cr, int *cb ) {
  541. int cc;
  542.     cc=Gdata[x+y*SizX];
  543.     *cb=Pal256->blue[cc];    /* パレットによる色変換 */
  544.     *cr=Pal256->red[cc];
  545.     *cg=Pal256->green[cc];
  546. }
  547.  
  548.  
  549. /* 輝度差データ取得 */
  550. void sum_ydata( int *ydt, int *sum, int *cnt ) {
  551. int i,a,b,k,yc;
  552.  
  553.     *sum=*cnt=0;
  554.     for( a=1; a<=2; a++ ) {
  555.         for( b=1; b<=2; b++ ) {
  556.             yc=ydt[a+b*4];                        /* 対象点の輝度 */
  557.             for( i=0; i<4; i++ ) {
  558.                 k=ydt[a+DirX[i]+(b+DirY[i])*4];    /* 隣接点の輝度 */
  559.                 if( k>=0 ) {
  560.                     k=yc-k;
  561.                     if( k>=0 ) {    /* 対象点の方が輝度が高い時 */
  562.                         *sum+=k;
  563.                         (*cnt)++;
  564.                     }
  565.                 }
  566.             }
  567.         }
  568.     }
  569. }
  570.